#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include "pthread.hpp"
#include "LockGurd.hpp"
#include <cstdio>
#include <unistd.h>

class ThreadData
{
public:
    ThreadData(const std::string name, pthread_mutex_t* pmutex)
        :_ThreadName(name)
        , _mutex(pmutex)
    {}
public:
    std::string _ThreadName;
    pthread_mutex_t* _mutex;
};
std::string GetThreadName()
{
    static int Number = 0;
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "thread-%d", ++Number);
    return buffer;
}
void Print(int i)
{
    std::cout << i << std::endl;
}
int ticket = 10000;
void GetTicket(ThreadData* td)
{
    while (true)
    {
        LockGuard lockg(td->_mutex);
        //pthread_mutex_lock(td->_mutex);
        if (ticket > 0)
        {
            usleep(10);
            printf("%s get a ticket %d\n", td->_ThreadName.c_str(), ticket);
            ticket--;
            //pthread_mutex_unlock(td->_mutex);
        }
        else
        {
            //pthread_mutex_unlock(td->_mutex);
            break;
        }
    }
}
int main()
{
    pthread_mutex_t* mutex = new pthread_mutex_t;
    pthread_mutex_init(mutex, nullptr);
    std::string name1 = GetThreadName();
    ThreadData td1(name1, mutex);
    Thread<ThreadData*> th1(name1, GetTicket, &td1);
    std::string name2 = GetThreadName();
    ThreadData td2(name2, mutex);
    Thread<ThreadData*> th2(name2, GetTicket, &td2);
    std::string name3 = GetThreadName();
    ThreadData td3(name3, mutex);
    Thread<ThreadData*> th3(name3, GetTicket, &td3);
    std::string name4 = GetThreadName();
    ThreadData td4(name4, mutex);
    Thread<ThreadData*> th4(name4, GetTicket, &td4);
    th1.Start();
    th2.Start();
    th3.Start();
    th4.Start();

    th1.Join();
    th2.Join();
    th3.Join();
    th4.Join();
    return 0;
}